Skip to main content

ArcGIS Widgets to Components Migration Status Report

Overview

Migrated the Hydrotrek DWD Suite React application from ArcGIS JS SDK 4.30.9 to 4.33, adopting the new component-based architecture while preserving all existing UI/UX functionality.

Migration Scope

  • Framework: React 18 + Vite, JavaScript
  • Previous Version: ArcGIS JS SDK 4.30.9
  • Target Version: ArcGIS JS SDK 4.33.0
  • Architecture Change: Class-based → Component-based (ArcGIS Map Components)

Dependencies Updated

Package.json Changes

{
"@arcgis/core": "^4.33.0", // Updated from 4.30.9
"@arcgis/map-components": "^4.33.0", // Added new
"@arcgis/map-components-react": "^4.33.0" // Updated from 4.30.7
}

CSS Theme References

  • Updated ESRI_CSS_THEME_REFS in src/constants_styles.jsx
  • Changed CDN URLs from 4.30 to 4.33

Major Architectural Changes

1. Map Component Migration

2D Maps (src/components/EsriMap.jsx)

  • Before: Imperative new Map() and new MapView()
  • After: Declarative <ArcgisMap> component
  • Widgets Migrated:
    • BasemapGallery<ArcgisBasemapGallery>
    • Home<ArcgisHome>
    • Expand<ArcgisExpand>
    • NavigationToggle<ArcgisNavigationToggle>
    • Compass<ArcgisCompass>

3D Maps (src/components/Esri3DMap.jsx)

  • Before: Imperative new SceneView()
  • After: Declarative <ArcgisScene> component
  • Additional Widgets:
    • <ArcgisZoom> for 3D-specific controls
  • Performance Optimizations: Applied qualityProfile="low" and disabled expensive rendering features

CIM Valve Sample (src/components/EsriMapCIMValveSample.jsx)

  • Migrated from imperative Map/MapView to <ArcgisMap> component
  • Preserved CIM symbol functionality and custom rendering

2. Event Handling Modernization

View Ready Events

  • Before: Manual view initialization and view.when()
  • After: onArcgisViewReadyChange event handler
  • Implementation: Used event?.detail || event?.target?.view pattern for compatibility

State Management

  • Implemented useRef and useMemo for stable prop references
  • Added initializedRef to prevent re-initialization
  • Used useCallback for performance optimization

3. API Modernization

Reactive Utils

  • Before: mapView.map.watch() (deprecated)
  • After: reactiveUtils.watch() from @arcgis/core/core/reactiveUtils
  • Files Updated:
    • src/components/EsriMap.jsx
    • src/components/Esri3DMap.jsx
    • src/map_utils/esri/HeatmapLayer.jsx

Label Placement

  • Issue: above-center placement invalid for polylines
  • Fix: Changed to center-along in src/map_utils/esri/parseLink.jsx
  • Result: Eliminated console warnings

4. Performance Optimizations

Layer Configuration

  • Added refreshInterval: 0 to disable auto-refresh
  • Set maxRecordCount: 2000 for large datasets
  • Implemented modern clustering with deconflictionStrategy: 'automatic'

3D Scene Optimizations

  • Disabled directShadowsEnabled and ambientOcclusionEnabled
  • Set momentumEnabled: false for navigation
  • Applied qualityProfile="low" for better performance

Label Optimizations

  • Added repeatLabel: false and deconflictionStrategy: 'automatic'
  • Set minScale: 0 and maxScale: 0 for consistent labeling

5. Icon Modernization

  • Before: esri-icon-basemap (deprecated)
  • After: basemap (Calcite Design System)
  • Files Updated: All map components using Expand widgets

Issues Encountered and Resolutions

1. Custom Element Registration

Issue: Custom element "arcgis-map" not found Root Cause: Missing custom element registration Resolution: Added to src/index.jsx:

import { defineCustomElements } from '@arcgis/map-components/dist/loader';
defineCustomElements(window);

2. Map Reset Behavior

Issue: Map kept resetting to initial position/zoom Root Cause: Props being passed directly to components causing re-renders Resolution:

  • Removed center, zoom, basemap props from components
  • Set values imperatively once in onArcgisViewReadyChange
  • Used useMemo for stable prop references

3. Theme Management

Issue: Dark/light theme not applying to ArcGIS components Root Cause: Missing theme class management Resolution:

  • Added esri-theme-dark and calcite-mode-dark class toggling
  • Implemented dynamic CSS loading in src/theme/index.jsx

4. 3D Scene Performance

Issue: Laggy 3D performance compared to previous architecture Root Cause: Missing performance optimizations Resolution:

  • Applied qualityProfile="low"
  • Disabled expensive rendering features
  • Optimized navigation settings

5. React Hooks Violation

Issue: useCallback used in JSX props causing hooks order violation Root Cause: Conditional hook usage in Esri3DNetworkMapPage.jsx Resolution: Moved useCallback to component top level

6. WebGL Framebuffer Errors

Issue: GL_INVALID_FRAMEBUFFER_OPERATION errors Root Cause: Zero-size containers Resolution: Added minHeight and minWidth styles to map containers

7. SceneLayer Query Errors

Issue: scenelayer:query-not-available errors Root Cause: Attempting to query unsupported layers Resolution: Added capability checks before querying:

if (!!layer?.capabilities?.query?.supported) {
await layer.queryFeatures(query);
}

Sources and References

Official Documentation

Community Resources and Real-World Examples

  • Using the New Component Structure with React - Esri Community discussion highlighting common React integration challenges and solutions, including:
    • Custom element registration requirements
    • Import statement dependencies for components
    • React lifecycle considerations with web components
    • Common pitfalls and troubleshooting approaches

Strategic Context and Timeline

Esri's Component Transition Strategy

Based on the official Esri blog post, our migration aligns with Esri's strategic direction:

  • Current Status: All widgets are being transitioned to web components
  • Deprecation Timeline: All widgets will be deprecated as early as Q1 2026
  • Removal Timeline: All widgets will be removed from the SDK as early as Q1 2027
  • Component Benefits:
    • Standards-based web components using Calcite Design System
    • Framework-agnostic approach
    • Better performance and modern development patterns
    • Future-proofing for upcoming SDK versions